package com.jim.director.framework.validation;

import com.jim.director.framework.annotation.Actor;
import com.jim.director.framework.annotation.Configure;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

/**
 * @Actor 注解校验器
 * 校验Actor注解的参数合法性和使用规范
 *
 * @author Jim
 * @date 2024/10/5
 */
public class ActorValidator implements AnnotationValidator {

    private static final int MIN_ORDER = 0;
    private static final int MAX_ORDER = 10000;

    @Override
    public ValidationResult validate(Class<?> clazz) {
        ValidationResult result = new ValidationResult(clazz.getSimpleName());

        // 只校验带有@Actor注解的类
        if (!clazz.isAnnotationPresent(Actor.class)) {
            return result;
        }

        Actor actor = clazz.getAnnotation(Actor.class);

        // 1. 校验order参数范围
        validateOrder(actor.order(), result, clazz);

        // 2. 校验类是否可实例化
        validateInstantiatable(clazz, result);

        // 3. 校验与@Configure注解的冲突
        validateConfigureConflict(clazz, result);

        // 4. 校验类的访问修饰符
        validateClassModifiers(clazz, result);

        return result;
    }

    /**
     * 校验order参数范围
     */
    private void validateOrder(int order, ValidationResult result, Class<?> clazz) {
        if (order < MIN_ORDER || order > MAX_ORDER) {
            result.addError(String.format(
                "类 %s 的 @Actor 注解: order参数值 %d 超出有效范围 [%d, %d]。" +
                "建议使用较小的正整数来表示执行优先级。",
                clazz.getSimpleName(), order, MIN_ORDER, MAX_ORDER
            ));
        }

        if (order == Integer.MAX_VALUE) {
            result.addWarning(String.format(
                "类 %s 的 @Actor 注解: 使用默认order值(Integer.MAX_VALUE)可能导致执行顺序不可预期。" +
                "建议显式指定order值。",
                clazz.getSimpleName()
            ));
        }
    }

    /**
     * 校验类是否可实例化
     */
    private void validateInstantiatable(Class<?> clazz, ValidationResult result) {
        // 检查是否为抽象类
        if (Modifier.isAbstract(clazz.getModifiers())) {
            result.addError(String.format(
                "类 %s 标注了 @Actor 注解，但是抽象类，无法实例化。" +
                "请移除abstract修饰符或移除@Actor注解。",
                clazz.getSimpleName()
            ));
            return;
        }

        // 检查是否为接口
        if (clazz.isInterface()) {
            result.addError(String.format(
                "接口 %s 不能标注 @Actor 注解。@Actor只能标注在具体类上。",
                clazz.getSimpleName()
            ));
            return;
        }

        // 检查是否有默认构造函数
        try {
            Constructor<?> defaultConstructor = clazz.getDeclaredConstructor();
            if (!Modifier.isPublic(defaultConstructor.getModifiers()) &&
                !Modifier.isProtected(defaultConstructor.getModifiers()) &&
                !isPackagePrivate(defaultConstructor.getModifiers())) {
                result.addWarning(String.format(
                    "类 %s 的默认构造函数不是public/protected/包私有访问级别，" +
                    "可能导致实例化失败。建议将构造函数设为public。",
                    clazz.getSimpleName()
                ));
            }
        } catch (NoSuchMethodException e) {
            result.addError(String.format(
                "类 %s 标注了 @Actor 注解，但没有默认构造函数。" +
                "请添加一个无参的public构造函数。",
                clazz.getSimpleName()
            ));
        }
    }

    /**
     * 校验与@Configure注解的冲突
     */
    private void validateConfigureConflict(Class<?> clazz, ValidationResult result) {
        if (clazz.isAnnotationPresent(Configure.class)) {
            result.addWarning(String.format(
                "类 %s 同时标注了 @Actor 和 @Configure 注解。" +
                "@Configure 注解已经隐含了Actor功能，建议移除 @Actor 注解以避免混淆。",
                clazz.getSimpleName()
            ));
        }
    }

    /**
     * 校验类的访问修饰符
     */
    private void validateClassModifiers(Class<?> clazz, ValidationResult result) {
        if (Modifier.isPrivate(clazz.getModifiers())) {
            result.addError(String.format(
                "类 %s 标注了 @Actor 注解，但是private类，框架无法访问。" +
                "请将类修改为public或包私有访问级别。",
                clazz.getSimpleName()
            ));
        }

        if (Modifier.isFinal(clazz.getModifiers())) {
            result.addWarning(String.format(
                "类 %s 标注了 @Actor 注解，但是final类。" +
                "虽然不影响功能，但可能限制框架的某些高级特性（如代理）。",
                clazz.getSimpleName()
            ));
        }
    }

    /**
     * 判断是否为包私有访问级别
     */
    private boolean isPackagePrivate(int modifiers) {
        return !Modifier.isPublic(modifiers) &&
               !Modifier.isPrivate(modifiers) &&
               !Modifier.isProtected(modifiers);
    }

    @Override
    public Class<?>[] getSupportedAnnotations() {
        return new Class<?>[]{Actor.class};
    }

    @Override
    public String getValidatorName() {
        return "ActorValidator";
    }
}

